Segmentation and windowing¶
Assuming that your data are in the right format (see the Data chapter for more details), you can now run an analysis. We first demo here the usage of the interface and at the end show how to run an analysis without the UI. If you are interested in the methods you can see more in-depth explanation of what is occurring behind the scenes in a step by step demo.
Creating the interface¶
The interface is generated via the InteracSeg class contained in the morpho_segmentation module:
from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteracSeg()
myUI.interface
from IPython.display import HTML
HTML(filename='images/UI_html.html')
The interface is composed of four parts:
Data handling:
In the Choose main folder you should browse to the folder containing your data.
In the Saving folder you should select to which folder you want to export results.
The Load Segmentation button allows to re-load an existing analysis.
Selecting channels in the Chose segmentation and signal channels (folders or tifs) section:
You should choose which channel you want to use for segmentation (left)
and from which channels you want to extract signal information (right). If you want to analyze the intensity of the segmentation channel, you have to select it as well as a signal.
Once selection is done you can load the data with the Initialize button.
Computing type: select cluster, if you want computations to be submitted via a SLURMCluster job-queue.
Set segmentation parameters:
Maxtime: select the last time point to be analyzed, by default the last available time point
Step: If for example you only want to analyze every second step, enter 2.
Bad frame: If you want to skip certain frames, enter them here, e.g. (e.g. 1,2,5-8,12)
Segmentation: Select your segmentation mode (see this chapter for more details)
Location X/Y: Location of the cell to track can be entered here manually.
Window depth/width: Desired dimensions (in px) of the windows.
Run the segmentation with the Click to segment button.
Save the results with the Save the segmentation button.
Plot: The central plot shows an image and its current windowing. One can adjust:
The Time (frame) and the intensity range of the current image.
Whether to show windows or show labels of windows.
Which channel should be displayed.
Finally, you can click on the image to select which cell (if there are multiple ones) to track.
Note that when creating the interface myUI = InteractSeg you can pass additional arguments to avoid having to select them in the interface. This is particularly useful if you are running tests and have to repeatedly create the interface. For example you can use:
from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteracSeg(expdir="path/to/my/data", seg_algo='ilastik')
myUI.interface
to specify where your data are and which algorithm to use. In that way you won’t have to browse to your data folder or change the algorithm.
Running a new analysis¶
In general follow these steps:
Choose the data folder and the place where to save your results in the top two file browsers
Choose which channels to use for segmentation and signal extraction in the Chose segmentation and signal channels (folders or tifs) part
Now you can Initialize data, i.e. load the data set. Now you should see the first frame displayed in the figure.
Select your computation resource and segmentation parameters.
Select the cell to track (if necessary) by clicking on the image.
Run the segmentation by clicking on Click to segment.
Browse through the results.
Save your data by clicking on Save segmentation.
Output¶
The results of the analysis are saved in the following way:
Segmentation images are saved in the
segmentedfolder assegmented_k_0.tif,segmented_k_1.tifetc. Those images are labelled masks, i.e. each cell gets one label.Tracking information is saved as binary images where only the selected cell appear. Images are called
tracked_k_0.tif,tracked_k_1.tifetc.The raasterized cell contours where pixel values correspond to curvilinear distance are stored as 32-bits images
rasterized_k_0.tif,rasterized_k_1.tifetc.The binary window images with window boundaries are stored as
window_image_k_0.tif,window_image_k_1.tifetc.The list of pixel indexes indicating to which window each pixel belongs are stored as pickle files
window_k_0.pkl,window_k_1.pkletc.Other information such as spline functions are stored in a pickled
Results.pklfile.Parameters of the experiments are saved in a human readable
Parameters.ymlfile.
Loading an existing analysis¶
In general follow these steps:
Choose the folder that contains your results (
Results.pklandParameters.ymlfiles).Cick on Load segmentation
You should now see a UI updated with all parameters set when analyzing the dataset.
Running an analysis without UI¶
In some cases it is preferable to use the code without the interface. This is in particular true if you want to run a batch of analysis. We present here an example of how to do that.
Just like before, we use the InteractSeg class defined in the morpho_segmentation module as an object that simplifies the handling of all the parts of the code. We need to provide the data location as well as a folder to save the data:
expdir = '../synthetic/data'
result_dir = '../synthetic/data/Results_step'
and specify which channels we intend to use. We need to provide the name of the stack used for segmentation:
morpho_name = 'synth_ch1.h5'
as well as a list of stack names whose intensity we want to analyze:
signal_name = ['synth_ch2.h5','synth_ch3.h5']
Now we can create our segmentation object:
from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteractSeg(expdir=expdir, morpho_name=morpho_name, signal_name=signal_name,
resultdir=result_dir, createUI=False)
It is important to know that the myUI instance of InteracSeg contains itself the main objects used for the analysis, Parameters, Results and Data as parameters, so there is no need to create them separately.
We can now load the data by initializing the experiment:
myUI.initialize()
Now we can adjust the parameters for the segmentation (seg_algo) and windowing (widht and depth)
myUI.param.width = 5
myUI.param.depth = 5
myUI.param.lambda_ = 10
myUI.param.seg_algo = 'ilastik'
Finally we can run the analysis:
myUI.run_segmentation()
frames splining: 0%| | 0/40 [00:00<?, ?it/s]
frames splining: 2%|▎ | 1/40 [00:04<03:10, 4.89s/it]
frames splining: 62%|██████▎ | 25/40 [00:04<00:51, 3.43s/it]
frames splining: 100%|██████████| 40/40 [00:05<00:00, 7.91it/s]
frames rasterize: 0%| | 0/39 [00:00<?, ?it/s]
frames rasterize: 3%|▎ | 1/39 [00:03<02:22, 3.75s/it]
frames rasterize: 38%|███▊ | 15/39 [00:03<01:03, 2.63s/it]
frames rasterize: 100%|██████████| 39/39 [00:03<00:00, 9.88it/s]
frames compute windows: 0%| | 0/40 [00:00<?, ?it/s]
frames compute windows: 0%| | 0/40 [00:00<?, ?it/s]
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-8-c5dcfd9178be> in <module>
----> 1 myUI.run_segmentation()
/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/morpho_segmentation.py in run_segmentation(self, b)
383 self.param,
384 self.client,
--> 385 skip_segtrack=self.skip_trackseg,
386 )
387 self.show_segmentation(change="init")
/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in analyze_morphodynamics(data, param, client, only_seg, keep_seg, skip_segtrack)
97
98 # create windows
---> 99 windowing_all(s_all, res.orig, param, J, I, client)
100
101 # define windows for each frame and compute pairs of corresponding
/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in windowing_all(s_all, ori_all, param, J, I, client)
357 ]
358 for k in tqdm(range(len(s_all)), "frames compute windows"):
--> 359 compute_windows[k].result()
360 compute_windows[k].cancel()
361
/usr/share/miniconda/lib/python3.7/site-packages/distributed/client.py in result(self, timeout)
223 if self.status == "error":
224 typ, exc, tb = result
--> 225 raise exc.with_traceback(tb)
226 elif self.status == "cancelled":
227 raise result
/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in windowing()
322 name2 = os.path.join(save_path, "window_image_k_" + str(k_iter) + ".tif")
323
--> 324 c = utils.load_rasterized(save_path, k_iter)
325 w, _, _ = create_windows(c, splevper(ori, s), J, I)
326
/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/utils.py in load_rasterized()
127
128 image = skimage.io.imread(
--> 129 os.path.join(location, "rasterized_k_" + str(frame) + ".tif")
130 )
131
/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/_io.py in imread()
46
47 with file_or_url_context(fname) as fname:
---> 48 img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
49
50 if not hasattr(img, 'ndim'):
/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/manage_plugins.py in call_plugin()
207 (plugin, kind))
208
--> 209 return func(*args, **kwargs)
210
211
/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/_plugins/tifffile_plugin.py in imread()
34
35 # read and return tiff as numpy array
---> 36 with TiffFile(fname, **kwargs_tiff) as tif:
37 return tif.asarray(**kwargs)
/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in __init__()
2792 raise TypeError(f'unexpected keyword argument: {key}')
2793
-> 2794 fh = FileHandle(arg, mode=mode, name=name, offset=offset, size=size)
2795 self._fh = fh
2796 self._multifile = bool(_multifile)
/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in __init__()
8295 self.is_file = None
8296 self._lock = NullContext()
-> 8297 self.open()
8298
8299 def open(self):
/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in open()
8308 self._file = os.path.realpath(self._file)
8309 self._dir, self._name = os.path.split(self._file)
-> 8310 self._fh = open(self._file, self._mode)
8311 self._close = True
8312 if self._offset is None:
FileNotFoundError: [Errno 2] No such file or directory: '/home/runner/work/MorphoDynamics/MorphoDynamics/synthetic/data/Results_step/segmented/rasterized_k_0.tif'
And save the output:
myUI.export_data()